www.gusucode.com > Sphero Connectivity Package 程序工具箱matlab源码 > Sphero Connectivity Package/simulink/sfun3d.m
function [sys, x0, str, ts] = sfun3d(~,~,u,flag,ax,varargin) %SFUN3D S-function that acts as an X-Y-Z scope using MATLAB plotting functions. % This M-file is designed to be used in a Simulink S-function block. % It draws a line from the previous input point and the current point. % % NOTE: this is a new version of sfunxyz. It has more natural inputs % that is (x1,y1,z1, x2,y2,z2 ... instead of x1,x2, y1,y2, z1,z2 ...) % and has the LineStyle and Marker properties as additional parameters, % so for versions 2014b and later users should try to use this one % instead of the older sfunxyz. % % See also sfunxy, sfunxys. % Copyright 2017 The MathWorks, Inc. % Based on original work by Andy Grace (May-91), Wes Wang (Apr-93, Aug-93, % Dec-93), Craig Santos (Oct-96), and Giampiero Campa (Apr-04, Nov-15, % Jan-17, Nov-17). switch flag case 0 % [sys,x0,str,ts]=mdlInitializeSizes (ax,varargin) ------------- % Returns the sizes, initial conditions, and sample times % Here is used also to set callbacks, and initialize the figure objects % version check vrs=version; if str2double(vrs(1:3))<8.4 error('This S-Function (sfun3d.m) works only within MATLAB versions 2014b and later. For older versions, please delete any existing version of 3Dscope, (re)install it with this MATLAB version, and use the legacy S-Function ''sfunxyz.m''.'); end % build callback strings (to be called when the user performs some actions on the block) callbacks={ 'CopyFcn', 'if exist(''sfun3d'',''file''), sfun3d([],[],[],''CopyBlock''); end'; 'DeleteFcn', 'if exist(''sfun3d'',''file''), sfun3d([],[],[],''DeleteBlock''); end'; 'LoadFcn', 'if exist(''sfun3d'',''file''), sfun3d([],[],[],''LoadBlock''); end'; 'NameChangeFcn', 'if exist(''sfun3d'',''file''), sfun3d([],[],[],''NameChange''); end'; 'StartFcn', ''; 'StopFcn', ''; }; % set callbacks as block properties (for these, flag is a string) for i=1:length(callbacks) if ~strcmp(get_param(gcbh,callbacks{i,1}),callbacks{i,2}) set_param(gcbh,callbacks{i,1},callbacks{i,2}) end end % ax was there in sfunxy, for everything else there's varargin if length(ax)~=6, error('Axes limits must be defined.'); end % get number of moving points (i.e. number of lines) to be plotted if nargin>6, nmax=fix(varargin{2}); else nmax=1; end sizes=simsizes; % this initializes size vector to zero sizes.NumInputs = 3*nmax; % input vector size at runtime sizes.NumSampleTimes = 1; % fill number of sample times % get sample time if nargin>5, ts=[varargin{1} 0]; else ts=[0.01 0]; end % return initialization values to simulink as function outputs sys=simsizes(sizes);x0=[];str=[]; % get the active figure parameter (toolbar and menubar) if nargin>13 && varargin{9}, tb='figure'; else tb='none'; end % do the figure initialization FigHandle=get_param(gcbh,'UserData'); if isempty(FigHandle) || ~ishandle(FigHandle) % the figure doesn't exist, create one FigHandle = figure(... 'Units', 'pixel',... 'Position', [100 100 400 300],... 'Name', get_param(gcbh,'Name'),... 'Tag', 'SIMULINK_3DGRAPH_FIGURE',... 'NumberTitle', 'off',... 'IntegerHandle', 'off',... 'Toolbar', tb,... 'Menubar', tb); else % otherwise clear it clf(FigHandle); end % get number of moving points, camera position, and grid switch if nargin>7, CPos=varargin{3}; else CPos=[3 2 1]*100; end if nargin>8 && varargin{4}, GdSw='On'; else GdSw='Off'; end % Note: the structure pd contains all the plot data and will be % later stored in the figure's userdata! % create axes pd.XYZAxes = axes('Parent',FigHandle); cord=get(pd.XYZAxes,'ColorOrder'); set(pd.XYZAxes,'Visible','on','Xlim', ax(1:2),'Ylim', ax(3:4),'Zlim', ax(5:6),'CameraPosition',CPos,'XGrid',GdSw,'YGrid',GdSw,'ZGrid',GdSw); % get LineStyle string, Marker string, and max num of line points if nargin>9, ls=varargin{5}; else ls='-'; end if nargin>10, mk=varargin{6}; else mk='none'; end if nargin>11, mx=varargin{7}; else mx=1e5; end % create a vector of animatedline objects pd.XYZLine = []; for n=1:nmax pd.XYZLine = [pd.XYZLine animatedline('Parent',pd.XYZAxes,'LineStyle',ls,'Marker',mk,'MaximumNumPoints',mx,'Color',cord(1+mod(n-1,size(cord,1)),:))]; end % create a vector of line object that will represent the current point position if nargin>12 && varargin{8} pd.XYZHead = []; mrks={'o';'square';'diamond';'v';'+';'*';'x';'^';'>';'<';'pentagram';'hexagram'}; for n=1:nmax pd.XYZHead = [pd.XYZHead line('Parent',pd.XYZAxes,'Marker',mrks{1+mod(n-1,size(mrks,1))},'Color',cord(1+mod(n-1,size(cord,1)),:))]; end end % create axis labels xlabel('X Axis');ylabel('Y Axis');zlabel('Z Axis'); % create plot title pd.XYZTitle = get(pd.XYZAxes,'Title'); set(pd.XYZTitle,'String','X Y Z Plot'); % Store pd so it can be later retrieved at runtime set(FigHandle,'UserData',pd); % store pd in figure's userdata set_param(gcbh,'UserData',FigHandle); % store figure handle in block's UserData case 2 % sys=mdlUpdate(~,~,u,~) --------------------------------------- % Handle discrete state updates, sample time hits, and major time step stuff % Here is used only to add another point to the lines % always return empty, as there are no states sys = []; % Locate the figure window associated with this block. If it's not a valid % handle (it may have been closed by the user), then return. FigHandle=get_param(gcbh,'UserData'); if isempty(FigHandle) || ~ishandle(FigHandle), return, end % get plot data structure pd = get(FigHandle,'UserData'); % add points to each line nmax=length(pd.XYZLine); for i=1:nmax addpoints(pd.XYZLine(i),u(3*(i-1)+1),u(3*(i-1)+2),u(3*(i-1)+3)); end % update head position if nargin>12 && varargin{8} for i=1:nmax set(pd.XYZHead(i),'xdata',u(3*(i-1)+1),'ydata',u(3*(i-1)+2),'zdata',u(3*(i-1)+3)); end end % Note: the following four callbacks were set by "case 0" above case 'NameChange' % --------------------------------------------------- % get the figure associated with this block, if it's valid, change % the name of the figure FigHandle=get_param(gcbh,'UserData'); if ishandle(FigHandle) set(FigHandle,'Name',get_param(gcbh,'Name')); end case {'CopyBlock', 'LoadBlock'} % ------------------------------------- % Initialize the block's UserData such that a figure is not associated with the block set_param(gcbh,'UserData',-1); case 'DeleteBlock' % -------------------------------------------------- % Get the figure handle associated with the block, if it exists, delete it FigHandle=get_param(gcbh,'UserData'); if ishandle(FigHandle) delete(FigHandle); set_param(gcbh,'UserData',-1); end case {3,9} % ---------------------------------------------------------- sys=[]; otherwise % ----------------------------------------------------------- if ischar(flag) errmsg=sprintf('Unhandled flag: ''%s''', flag); else errmsg=sprintf('Unhandled flag: %d', flag); end error(errmsg); end % end sfun3d